/**
 * @Author: zhongyang
 * @Date: 2022/6/27 16:57
 */

package main

import "fmt"

/**
12_装饰器模式
概念：动态地给一个对象添加一些额外的职责。就增加功能来说，相比生成子类更为灵活。
和代理模式有点相似，但是代理模式一般用于业务本身无关的逻辑，而装饰器模式则是增强功能。
*/

// 同一个包下不能够重名，前面加个D区分一下
type DComponent interface {
	Calc() int
}

type ConcreteComponent struct {
}

func (c *ConcreteComponent) Calc() int {
	return 0
}

// 乘法修饰器
type MulDecorator struct {
	DComponent
	num int
}

func NewMulDecorator(DComponent DComponent, num int) *MulDecorator {
	return &MulDecorator{DComponent: DComponent, num: num}
}

func (m *MulDecorator) Calc() int {
	return m.DComponent.Calc() * m.num
}

// 加法修饰器
type AddDecorator struct {
	DComponent
	num int
}

func NewAddDecorator(DComponent DComponent, num int) *AddDecorator {
	return &AddDecorator{DComponent: DComponent, num: num}
}

func (a *AddDecorator) Calc() int {
	return a.DComponent.Calc() + a.num
}

func main() {
	var dc DComponent
	dc = &ConcreteComponent{}
	dc = NewAddDecorator(dc, 1)
	dc = NewMulDecorator(dc, 10)
	fmt.Println(dc.Calc())
}
